package org.finesys.samples.file.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NioServer {


    public static void main(String[] args) {
        ByteBuffer readBuffer = ByteBuffer.allocate(1024);
        ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
        try {
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);//显示配置非阻塞模式，否则会抛异常IllegalBlockingModeException
            serverSocketChannel.bind(new InetSocketAddress(8080));
            //创建一个selector选择器，把Channel注册到selector选择器上，监听accept事件
            Selector selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("服务器已启动，等待客户端连接");
            while (true) {
                System.out.println("等待事件发生");
                //阻塞等待事件
                int readChannels = selector.select();
                if (readChannels == 0) {
                    continue;
                }
                System.out.println("事件发生了");
                //处理事件
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterable = selectionKeys.iterator();
                while (iterable.hasNext()) {
                    SelectionKey selectionKey = iterable.next();
                    SocketChannel socketChannel = null;
                    try {
                        if (selectionKey.isAcceptable()) {
                            //处理连接请求accept事件
                            ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();
                            socketChannel = ssc.accept();
                            socketChannel.configureBlocking(false);
                            socketChannel.register(selector, SelectionKey.OP_READ);
                        } else if (selectionKey.isReadable()) {
                            //处理read事件
                            socketChannel = (SocketChannel) selectionKey.channel();
                            readBuffer.clear();
                            int count = socketChannel.read(readBuffer);
                            if (count > 0) {
                                String receiveMessage = new String(readBuffer.array());
                                System.out.println("接收到客户端消息" + receiveMessage);
                                socketChannel.register(selector, SelectionKey.OP_WRITE);
                            }
                        } else if (selectionKey.isWritable()) {
                            //处理write事件
                            socketChannel = (SocketChannel) selectionKey.channel();
                            //给客户端发送消息
                            String sendMessage = "你好，客户端！";
                            sendBuffer.clear();
                            sendBuffer.put(sendMessage.getBytes());
                            sendBuffer.flip();
                            socketChannel.write(sendBuffer);
                            System.out.println("服务端向客户端发送数据：" + sendMessage);
                            socketChannel.register(selector, SelectionKey.OP_READ);
                        }
                        //处理完成后，将事件从selectionKeys里面移除掉
                        iterable.remove();
                    } catch (IOException e) {
                        selectionKey.cancel();
                        if (socketChannel != null) {
                            socketChannel.close();
                        }
                        System.out.println("客户端关闭:" + e.getMessage());
                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }


}
